﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
using AMM.Business;
using AMM.Business.Project;
using AMM.CustomClassLibrary;
using AMM.CustomWinComponents.Validator;
using AMM.CustomWinControls;
using AMM.Model;
using AMM.Model.Project;
using AMM.UserControls;

namespace AMM.Forms.Project {
    public partial class FrmMaterial : FrmMaterialBase {

        private int _pageIndex;
        private MaterialSearchModel _searchModel;
        private MaterialProcessor _materialProcessor;
        private List<MaterialViewModel> _materialList;

        #region Override

        protected override string FunctionCode {
            get { return "AMM1301"; }
        }

        protected override BaseSearchControl SearchControl {
            get { return new MaterialSearchControl(); }
        }

        protected override void Add() {
            this.ResetForms();
            this.FBS.CurrentItem = new Material() { IsEnabled = true, ClassStatus = ClassStatus.Added };

            this.gbMaterialInfo.Enabled = true;
            this.validator.ClearAllControlErrorIcons();
            base.Add();
        }

        protected override void Amend() {
            List<MaterialViewModel> selectedList = this.dgvMaterialList.GetSelectedRows<MaterialViewModel>();
            if (selectedList.Count > 1) { this.OnlySelectSingleRecord(); return; }
            if (selectedList.Count == 0) { this.ShouldSelectSingleRecord(); return; }
            Material material = this._materialProcessor.FetchMaterialById(selectedList[0].Key);
            material.ClassStatus = ClassStatus.Updated;
            this.FBS.CurrentItem = material;
            this.gbMaterialInfo.Enabled = true;
            base.Amend();
        }

        protected override void Save() {
            this.CreateNewThread(() => {
                this.PreventCancel = true;
                Material material = this.FBS.CurrentItem;

                if (material.ClassStatus == ClassStatus.Added) {
                    material.CreatedBy = LoginUserName;
                    this._materialProcessor.Insert(material);
                }
                else {
                    material.ModifiedBy = LoginUserName;
                    this._materialProcessor.Update(material);
                }

                this.MDIParent.SetStatusInformation("保存成功");
            }, () => {
                this.ResetForms();
                this.PreventCancel = false;
                base.Save();
            });
        }

        protected override void Delete() {
            List<MaterialViewModel> selectedList = this.dgvMaterialList.GetSelectedRows<MaterialViewModel>();
            if (selectedList.Count == 0) { this.ShouldSelectSingleRecord(); return; }
            this.CreateNewThread(() => {
                this.PreventCancel = true;
                this._materialProcessor.Delete(selectedList.Select(x => x.Key).ToArray());
                this.MDIParent.SetStatusInformation("删除成功");
            }, () => {
                this.ResetForms();
                this.PreventCancel = false;
            });
            base.Delete();
        }

        protected override void Search(object sender, FrmSearch.SearchArgs e) {
            this.CreateNewThread(() => {
                if (e.IsRevert) {
                    this._searchModel = new MaterialSearchModel();
                }
                else {
                    this._searchModel = (MaterialSearchModel)e.SearchModel;
                }
            }, () => {
                this.BindMaterialList();
            });
        }

        #endregion

        public FrmMaterial() {
            this.InitializeComponent();

            this.dgvMaterialList.DataGridViewModelType = typeof(MaterialViewModel);
        }

        #region Private methods

        private void ResetForms() {
            this.BindMaterialList();
            this.attachment.Reset();
            this.FBS.CurrentItem = null;
            this.gbMaterialInfo.Enabled = false;
        }

        private void CreateFormBindings() {
            this.FBS.CreateBinding(this.tbCode, x => x.Text, y => y.Code);
            this.FBS.CreateBinding(this.tbName, x => x.Text, y => y.Name);
            this.FBS.CreateBinding(this.cmbMaterialType, x => x.SelectedValue, y => y.MaterialTypeId);
            this.FBS.CreateBinding(this.cmbUnit, x => x.SelectedValue, y => y.UnitId);
            this.FBS.CreateBinding(this.tbPreserveAmount, x => x.Text, y => y.PreserveAmount, z => z.ToString("G0"));
            this.FBS.CreateBinding(this.tbRemarks, x => x.Text, y => y.Remarks);
            this.FBS.CreateBinding(this.cbIsEnabled, x => x.Checked, y => y.IsEnabled);
            this.FBS.CreateBinding(this.attachment, x => x.Text, y => y.AttachmentId, DataSourceUpdateMode.OnPropertyChanged);
        }

        private void BindMaterialList() {
            this.CreateNewThread(() => {
                this._materialList = this._materialProcessor.FetchMaterialViewModelList(this._searchModel, this._pageIndex);
            }, () => {
                this.dgvMaterialList.DataSource = new SortableBindingList<MaterialViewModel>(this._materialList);
                this.pceList.Records = this._searchModel.Records;
                this.pceList.DataBind();
            });
        }

        private void BindValidation() {
            this.validator.SetType(this.tbCode, ValidationType.Required);
            this.validator.SetRequiredMessage(this.tbCode, this.RequiredMessage);

            this.validator.SetType(this.tbName, ValidationType.Required);
            this.validator.SetRequiredMessage(this.tbName, this.RequiredMessage);

            this.validator.SetType(this.cmbMaterialType, ValidationType.Required);
            this.validator.SetRequiredMessage(this.cmbMaterialType, this.RequiredMessage);

            this.validator.SetType(this.cmbUnit, ValidationType.Required);
            this.validator.SetRequiredMessage(this.cmbUnit, this.RequiredMessage);

            this.validator.SetType(this.tbPreserveAmount, ValidationType.Required | ValidationType.RegularExpression);
            this.validator.SetRequiredMessage(this.tbPreserveAmount, this.RequiredMessage);
            this.validator.SetRegularExpression(this.tbPreserveAmount, "^([0-9]+.)?[0-9]+$");
            this.validator.SetRegularExpressionMessage(this.tbPreserveAmount, "安全库存只能由数字组成");
        }

        #endregion

        private void FrmMaterial_Load(object sender, EventArgs e) {
            this.CreateNewThread(() => {
                this.PreventCancel = true;
                this.FBS = new FlexBindingSource<Material>();

                this._materialProcessor = new MaterialProcessor(this.pceList.PageSize);
                this._searchModel = new MaterialSearchModel();
                this._pageIndex = 1;
            }, () => {
                this.WindowState = FormWindowState.Maximized;

                this.BindBasics(this.cmbMaterialType, BasicsType.MaterialType);
                this.BindBasics(this.cmbUnit, BasicsType.UnitType);
                this.BindMaterialList();
                this.CreateFormBindings();
                this.BindValidation();
                this.ResetForms();
                this.PreventCancel = false;
            });
        }

        private void pceList_Paging(object sender, PaginationArgs e) {
            this._pageIndex = e.PageIndex;
            this.BindMaterialList();
        }
    }
}
